﻿using ConfExpert.Forms.Base;
using ConfExpert.Utility;
using DevExpress.Skins;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraPrinting;
using DevExpress.XtraPrinting.Preview;
using DevExpress.XtraReports.UI;
using DevTeam;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace ConfExpert.Forms.Depo.Kauf
{
    public partial class OrtakKumas : XForm
    {
        public int TelaCikisEmriId { get; set; }
        public int CikisEmriId { get; set; }

        public OrtakKumas()
        {
            InitializeComponent();
        }
        public OrtakKumas(string idx, int customerId, string sp, bool isRequestable)
            : this()
        {
            PlanlamaIds = idx;
            CustomerId = customerId;
            Sp = sp;
            IsRequestable = isRequestable;
        }

        BindingSource bsArticles, bsFoys, bsRolls;
        string PlanlamaIds, Sp;
        //int count = 1;
        int CustomerId;
        bool IsRequestable;
        private void OrtakKumas_Load(object sender, EventArgs e)
        {
            bbiOrtakKumas.Enabled = bbiCikisOlustur.Enabled = IsRequestable;
            ds.Merge(Session.DataManager.ExecuteDataSet(Sp, PlanlamaIds, CustomerId));

            DataRelation FK_OrtakKumas = new DataRelation("FK_OrtakKumas",
              ds.Tables["Table"].Columns["ProductId"],
              ds.Tables["Table1"].Columns["ProductId"]);
            ds.Relations.Add(FK_OrtakKumas);

            DataRelation FK_Product_rolls = new DataRelation("FK_Product_rolls",
              ds.Tables["Table"].Columns["ProductId"],
              ds.Tables["Table2"].Columns["ProductId"]);
            ds.Relations.Add(FK_Product_rolls);

            ds.Tables["Table2"].Columns.Add("KesilecekMiktar", typeof(decimal));
            ds.Tables["Table2"].Columns.Add("Seç", typeof(bool));
            ds.Tables["Table2"].Columns.Add("SelectedQty", typeof(decimal), "Iif(ISNULL(KesilecekMiktar,0)=0 and Seç=1, Qty, ISNULL(KesilecekMiktar,0))");
            ds.Tables["Table2"].Columns.Add("KaliteKontrol", typeof(int), "Iif(ISNULL(KaliteKontrolId,0) in (2,3,4,5,7), 1, 0)");
            ds.Tables["Table1"].Columns.Add("CikilacakMetraj", typeof(decimal));
            ds.Tables["Table"].Columns.Add("AvailableQty", typeof(decimal), "Sum(Child(FK_Product_rolls).Qty)");
            ds.Tables["Table"].Columns.Add("SelectedQty", typeof(decimal), "Sum(Child(FK_Product_rolls).SelectedQty)");
            ds.Tables["Table"].Columns.Add("OrtakKumasAdedi", typeof(decimal), "Sum(Child(FK_OrtakKumas).OrtakKumas)");
            ds.Tables["Table"].Columns.Add("CikilacakMetraj", typeof(decimal), "Sum(Child(FK_OrtakKumas).CikilacakMetraj)");
            ds.Tables["Table"].Columns.Add("Fark", typeof(decimal), "SelectedQty-ToplamIhtiyac");
            ds.Tables["Table"].Columns.Add("Fark2", typeof(decimal), "SelectedQty-CikilacakMetraj");

            bsArticles = new BindingSource(ds, "Table");
            bsFoys = new BindingSource(bsArticles, "FK_OrtakKumas");
            bsRolls = new BindingSource(bsArticles, "FK_Product_rolls");

            InitGridView(gvArticles, bsArticles);
            InitGridView(gvFoys, bsFoys);
            InitGridView(gvRolls, bsRolls);

            gvRolls.Columns["KesilecekMiktar"].VisibleIndex = gvRolls.Columns["Qty"].VisibleIndex + 1;
            gvRolls.MakeColumnInvisible("Scan", "ProductId", "SelectedQty", "KaliteKontrol","Seç");
            gvRolls.FormatAsNumber(1, "Qty", "SelectedQty", "KesilecekMiktar");
            gvRolls.SetCaptions("RollId:Top No", "Qty:Metraj");
            gvRolls.MakeReadOnly("KesilecekMiktar");


            gvFoys.MakeColumnInvisible("Scan", "ProductId", "OrtakKumas");
            gvFoys.SetCaptions("PastalBirimMetraj:Birim Metraj");
            gvFoys.MakeReadOnly("CikilacakMetraj");

            gvArticles.MakeColumnInvisible("OrtakKumasAdedi", "CikilacakMetraj", "Fark2");
            gvArticles.SetCaptions("Total:Adet", "SelectedQty:Seçilen Metraj", "AvailableQty:Stok Miktarı");
            gvArticles.FormatAsNumber(1, "ToplamIhtiyac", "SelectedQty", "Fark", "AvailableQty", "CikilacakMetraj");
            gvArticles.MakeReadOnly("Notlar");


            gvArticles.AddSummary("Total");
            gvFoys.AddSummary("Ihtiyac", "CikilacakMetraj");

            gvFoys.OptionsView.EnableAppearanceEvenRow =
            gvFoys.OptionsView.EnableAppearanceOddRow =
            gvArticles.OptionsView.EnableAppearanceOddRow =
            gvArticles.OptionsView.EnableAppearanceEvenRow =
            gvRolls.OptionsView.EnableAppearanceOddRow =
            gvRolls.OptionsView.EnableAppearanceEvenRow = false;


            GridManager gm;
            gm = GridManager.GetManager(gvRolls);
            gm.GridMenu.AddMenu("Seç", AddRolls);
            gm.GridMenu.AddMenu("Bırak", RemoveRolls);

            gm = GridManager.GetManager(gvArticles);
            gm.GridMenu.AddMenu("Seç", AddRolls1);
            gm.GridMenu.AddMenu("Bırak", RemoveRolls1);
            gm.GridMenu.AddMenu("Uygun Topları Seç", SelectBySubsetSum);

            gm = GridManager.GetManager(gvFoys);
            gm.GridMenu.AddMenu("Eksik/Fazla metrajı satırlara dağıt", DivideEqually);
            gm.GridMenu.AddMenu("Eksik/Fazla metrajı bu satıra ekle/çıkar", AddRemoveMeters);

            gvArticles.RowStyle += gvArticles_RowStyle;
            gvArticles.RowCellStyle += gvArticles_RowCellStyle;
            gvRolls.CellValueChanged += gvRolls_CellValueChanged;
            gvRolls.RowStyle += gvRolls_RowStyle;
            gvFoys.RowStyle += gvFoys_RowStyle;
            
            gvArticles.BestFitColumns();
            gvFoys.BestFitColumns();
            gvRolls.BestFitColumns();
        }

        private void AddRemoveMeters(object sender, EventArgs e)
        {
            string ProductId = gvFoys.GetFocusedRowCellValue("ProductId").ToStr();
            int CountSiparis = ds.Tables["Table1"].Select("OrtakKumas=1 and ProductId =" + ProductId).Length;

            if (CountSiparis > 1)
            {
                decimal SelectedQty = ds.Tables["Table2"].Compute("Sum(SelectedQty)", "ProductId =" + ProductId).ToDecimal();
                decimal FarkMutlak = Math.Abs(gvArticles.GetFocusedRowCellValue("Fark2").ToDecimal());

                if (SelectedQty > 0 && FarkMutlak > (decimal)0.5)
                {
                    //string idx = gvFoys.GetFocusedRowCellValue("idx").ToStr();
                    //DataRow dr = ds.Tables["Table1"].Select("OrtakKumas=1 and ProductId =" + ProductId + " and idx =" + idx)[0];

                    decimal Fark = gvArticles.GetFocusedRowCellValue("Fark2").ToDecimal();
                    decimal CikilacakMetraj = gvFoys.GetFocusedRowCellValue("CikilacakMetraj").ToDecimal();

                    if (Fark + CikilacakMetraj < 0)
                        gvFoys.SetFocusedRowCellValue("CikilacakMetraj", null);
                    else
                        gvFoys.SetFocusedRowCellValue("CikilacakMetraj", Fark + CikilacakMetraj);
                }
            }
        }

        private void DivideEqually(object sender, EventArgs e)
        {
            string ProductId = gvFoys.GetFocusedRowCellValue("ProductId").ToStr();
            int CountSiparis = ds.Tables["Table1"].Select("OrtakKumas=1 and ProductId =" + ProductId).Length;

            if (CountSiparis > 1)
            {
                decimal SelectedQty = ds.Tables["Table2"].Compute("Sum(SelectedQty)", "ProductId =" + ProductId).ToDecimal();
                decimal QtyIhtiyac = ds.Tables["Table1"].Compute("Sum(Ihtiyac)", "OrtakKumas = 1 and ProductId =" + ProductId).ToDecimal();
                decimal Fark = Math.Abs(gvArticles.GetFocusedRowCellValue("Fark2").ToDecimal());
                if (SelectedQty > 0 && Fark > (decimal)0.5)
                {
                    decimal carpan = (decimal)(SelectedQty / QtyIhtiyac);
                    DataRow[] drSiparisSatirlari = ds.Tables["Table1"].Select("OrtakKumas=1 and ProductId =" + ProductId);
                    foreach (DataRow dr in drSiparisSatirlari)
                    {
                        dr["CikilacakMetraj"] = decimal.Round((decimal)dr["Ihtiyac"] * carpan, 2);
                    }
                }
            }
        }

        void gvArticles_RowStyle(object sender, RowStyleEventArgs e)
        {
            Skin GridSkin = GridSkins.GetSkin(this.LookAndFeel.ActiveLookAndFeel);
            SkinElement EvenRowSkin = GridSkin[GridSkins.SkinGridEvenRow];
            SkinElement OddRowSkin = GridSkin[GridSkins.SkinGridOddRow];
            Color OddBackColor = OddRowSkin.Color.BackColor;
            Color EvenBackColor = EvenRowSkin.Color.BackColor;

            if (e.RowHandle > -1)
            {
                decimal SelectedQty = gvArticles.GetRowCellValue(e.RowHandle, "SelectedQty").ToDecimal();
                decimal Fark = Math.Abs(gvArticles.GetRowCellValue(e.RowHandle, "Fark2").ToDecimal());
                int OrtakKumas = gvArticles.GetRowCellValue(e.RowHandle, "OrtakKumasAdedi").ToInt();


                if (SelectedQty > 0 && Fark > (decimal)0.5 && OrtakKumas > 1)
                    e.Appearance.BackColor = e.Appearance.BackColor2 = Color.LightPink;
                else
                {
                    bool a = (e.RowHandle & 1) != 0;
                    if (a)
                        e.Appearance.BackColor = OddBackColor;
                    else
                        e.Appearance.BackColor = EvenBackColor;
                }

            }
        }

        void gvRolls_CellValueChanged(object sender, CellValueChangedEventArgs e)
        {
            gvRolls.EndEditing();

            if (e.Column.FieldName == "KesilecekMiktar")
            {
                string ProductId = gvRolls.GetRowCellValue(e.RowHandle, "ProductId").ToStr();
                SetCikilacakMiktar(ProductId);
            }
        }

        void SelectUnselectRolls(DataRow dr, bool sec)
        {
            gvRolls.EndEditing();
            dr["Seç"] = sec;

            string ProductId = dr["ProductId"].ToStr();
            SetCikilacakMiktar(ProductId);
        }

        void SetCikilacakMiktar(string ProductId)
        {
            int CountSiparis = ds.Tables["Table1"].Select("OrtakKumas=1 and ProductId =" + ProductId).Length;

            if (CountSiparis == 1)
            {
                DataRow drSiparis = ds.Tables["Table1"].Select("OrtakKumas=1 and ProductId =" + ProductId)[0];
                decimal SelectedQty = ds.Tables["Table2"].Compute("Sum(SelectedQty)", "ProductId =" + ProductId).ToDecimal();

                drSiparis["CikilacakMetraj"] = SelectedQty;
            }

            else
            {
                decimal SelectedQty = ds.Tables["Table2"].Compute("Sum(SelectedQty)", "ProductId =" + ProductId).ToDecimal();
                DataRow[] drSiparisSatirlari = ds.Tables["Table1"].Select("OrtakKumas=1 and ProductId =" + ProductId);
                foreach (DataRow dr in drSiparisSatirlari)
                {
                    if (SelectedQty > 0)
                        dr["CikilacakMetraj"] = dr["Ihtiyac"];
                    else
                        dr["CikilacakMetraj"] = DBNull.Value;
                }
            }
        }

        void OrtakKumas_ColumnChanged(object sender, DataColumnChangeEventArgs e)
        {
            gvRolls.EndEditing();
            if ("Seç KesilecekMiktar".Contains(e.Column.ColumnName))
            {
                int ProductId = e.Row["ProductId"].ToInt();
                int CountSiparis = ds.Tables["Table1"].Select("OrtakKumas=1 and ProductId =" + ProductId).Length;

                if (CountSiparis == 1)
                {
                    DataRow drSiparis = ds.Tables["Table1"].Select("OrtakKumas=1 and ProductId =" + ProductId)[0];
                    decimal SelectedQty = ds.Tables["Table2"].Compute("Sum(SelectedQty)", "ProductId =" + ProductId).ToDecimal();

                    drSiparis["CikilacakMetraj"] = SelectedQty;
                }
            }
        }

        void gvArticles_RowCellStyle(object sender, RowCellStyleEventArgs e)
        {
            if (e.RowHandle > -1)
            {

                if (e.Column.FieldName == "SelectedQty")
                {
                    e.Appearance.Font = new Font(DevExpress.Utils.AppearanceObject.DefaultFont, FontStyle.Bold);
                }

                if (e.Column.FieldName == "Fark")
                {
                    if (gvArticles.GetRowCellValue(e.RowHandle, "Fark").ToInt() < 0)
                        e.Appearance.ForeColor = Color.Red;
                    else
                        e.Appearance.ForeColor = Color.Green;
                }
            }
        }

        void gvFoys_RowStyle(object sender, RowStyleEventArgs e)
        {
            if (intParse(((GridView)sender).GetRowCellDisplayText(e.RowHandle, "OrtakKumas")) == 1)
                e.Appearance.BackColor = Color.LightBlue;
        }

        void gvRolls_RowStyle(object sender, RowStyleEventArgs e)
        {
            //if (((GridView)sender).GetRowCellDisplayText(e.RowHandle, "SelectedQty").ToStr() != string.Empty)
            if (((GridView)sender).GetRowCellValue(e.RowHandle, "SelectedQty").ToDecimal() > 0)
                e.Appearance.BackColor = Color.LightBlue;
        }

        void SelectBySubsetSum(object sender, EventArgs e)
        {
            int[] selectedRowIds = gvArticles.GetSelectedRows();
            List<int> selectedRollIds = new List<int>();

            foreach (int rowIndex in selectedRowIds)
            {
                int productId = (int)gvArticles.GetDataRow(rowIndex)["ProductId"];
                decimal target = Convert.ToDecimal(gvArticles.GetDataRow(rowIndex)["ToplamIhtiyac"]);

                DataRow[] drLines = ds.Tables["Table2"].Select("ProductId =" + productId);

                Dictionary<int, decimal> rolls = new Dictionary<int, decimal>();
                foreach (DataRow dr in drLines)
                {
                    int rollID = (int)dr["RollId"];
                    decimal qty = Convert.ToDecimal(dr["Qty"]);
                    rolls.Add(rollID, qty);
                }

                List<int> selectedRollId = SubsetSum.Select(target, rolls);
                selectedRollIds.AddRange(selectedRollId);
            }

            string strRollIds = string.Join(", ", Array.ConvertAll(selectedRollIds.ToArray(), i => i.ToString()));

            DataRow[] drSelectedRows = ds.Tables["Table2"].Select("RollId in (" + strRollIds + ")");
            foreach (DataRow dr in drSelectedRows)
            {
                SelectUnselectRolls(dr, true);
                //dr["Seç"] = true;
            }

            Clipboard.SetText(strRollIds);
        }

        void AddRolls1(object sender, EventArgs e)
        {
            foreach (int handle in gvArticles.GetSelectedRows())
            {

                //gridView2.SetRowCellValue(handle, gridView2.Columns["Seç"], true);

                int ProductId = gvArticles.GetRowCellValue(handle, "ProductId").ToInt();
                foreach (DataRow r in ds.Tables["Table2"].Select("ProductId = " + ProductId.ToString()))
                    SelectUnselectRolls(r, true);//r["Seç"] = true;

            }

            gvArticles.RefreshData();
            gvRolls.RefreshData();
        }

        void RemoveRolls1(object sender, EventArgs e)
        {
            foreach (int handle in gvArticles.GetSelectedRows())
            {
                int ProductId = gvArticles.GetRowCellValue(handle, "ProductId").ToInt();
                foreach (DataRow r in ds.Tables["Table2"].Select("ProductId = " + ProductId.ToString()))
                {
                    SelectUnselectRolls(r, false);
                    r["KesilecekMiktar"] = DBNull.Value;
                    //r["Seç"] = false;
                }
            }

            gvArticles.RefreshData();
            gvRolls.RefreshData();
        }

        void RemoveRolls(object sender, EventArgs e)
        {
            foreach (int handle in gvRolls.GetSelectedRows())
            {
                string RollId = gvRolls.GetRowCellValue(handle, "RollId").ToStr();
                DataRow dr = ds.Tables["Table2"].Select("RollId = " + RollId)[0];
                SelectUnselectRolls(dr, false);
                dr["KesilecekMiktar"] = DBNull.Value;
                //gvRolls.SetRowCellValue(handle, "Seç", false);
            }

            gvArticles.RefreshData();
            gvRolls.RefreshData();
        }

        void AddRolls(object sender, EventArgs e)
        {
            foreach (int handle in gvRolls.GetSelectedRows())
            {
                string RollId = gvRolls.GetRowCellValue(handle, "RollId").ToStr();
                DataRow dr = ds.Tables["Table2"].Select("RollId = " + RollId)[0];
                SelectUnselectRolls(dr, true);
                //gvRolls.SetRowCellValue(handle, "Seç", true);
            }
            gvArticles.RefreshData();
            gvRolls.RefreshData();
        }

        private void bbiOrtakKumas_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            gvArticles.EndEditing();
            gvFoys.EndEditing();
            DataRow[] drTop = ds.Tables["Table2"].Select("Seç=1 or KesilecekMiktar is not null");
            if (drTop.Length == 0)
            {
                ShowErrorMessage("Hiç top seçmediniz !");
                return;
            }

            string xmlArticle = ds.Tables["Table"].Serialize();
            string xmlFoys = ds.Tables["Table1"].Serialize();
            string xmlRolls = ds.Tables["Table2"].Serialize();
            int brandId = ds.Tables["Table3"].Rows[0]["BrandId"].ToInt(-1);
            string dosyaNo = ds.Tables["Table3"].Rows[0]["DosyaNo"].ToString();

            string OrtakKumasSpName = Sp.Replace("Get", "Create");
            OrtakKumasRaporu okr = new OrtakKumasRaporu(xmlArticle, xmlRolls, PlanlamaIds, "", CustomerId, OrtakKumasSpName, true);
            okr.ShowPreviewDialog();
        }

        private void bbiCikisOlustur_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            gvArticles.EndEditing();
            gvFoys.EndEditing();
            DataRow[] drMetrajEslesmeyen = ds.Tables["Table"].Select("OrtakKumasAdedi > 1 and Isnull(SelectedQty,0) > 0 and (Fark2 > 0.5 or Fark2 < -0.5)");
            if (drMetrajEslesmeyen.Length > 0)
            {
                ShowErrorMessage("Kırmızı renkli satırlar için seçtiğiniz metrajı sipariş satırlarına uygun şekilde dağıtmalısınız");
                return;
            }

            DataRow[] drTop = ds.Tables["Table2"].Select("Seç=1 or KesilecekMiktar is not null");
            if (drTop.Length == 0)
            {
                ShowErrorMessage("Hiç top seçmediniz !");
                return;
            }

            string Message = "";

            //Seçilen fireli toplar
            DataRow[] drKaliteKontrol = ds.Tables["Table2"].Select("(Seç=1 or KesilecekMiktar is not null) and KaliteKontrol = 1");
            if (drKaliteKontrol.Length > 0)
            {
                Message += "DİKKAT!!! FİRELİ TOPLARI SEÇTİNİZ :\n";
                foreach (DataRow drKalite in drKaliteKontrol)
                {
                    int ProductId = drKalite["ProductId"].ToInt();
                    int KaliteKontrolId = drKalite["KaliteKontrolId"].ToInt();
                    string RollId = drKalite["RollId"].ToStr();
                    string KumasKodu = AppSession.Lookups.V_Kumas.FindByProductId(ProductId).Name;
                    string KaliteKontrol = AppSession.Lookups.KaliteKontrol.FindByKaliteKontrolId(KaliteKontrolId).Name;

                    Message += KumasKodu + " - " + RollId + " - " + KaliteKontrol + "\n";
                }
            }

            Message += "\nSEÇİLEN TOPLARDAKİ AYRIMLAR(Marka. OrderRef. Sezon) :\n";

            //Çıkılan toplardaki ayrımlar
            DataTable dtAyrimlar = ds.Tables["Table2"].Select("Seç=1 or KesilecekMiktar is not null").CopyToDataTable().DefaultView.ToTable(true, "AyrimId");
            foreach (DataRow drAyrim in dtAyrimlar.Rows)
            {
                string OrderRef = AppSession.Lookups.Ayrim.FindByAyrimId(drAyrim["AyrimId"].ToInt()).Reference;
                Message += OrderRef + "\n";
            }            

            //Seçilen kumaşlardan %10 dan daha fazla metrajlı olanlar
            DataRow[] drSelectedQty = ds.Tables["Table"].Select("Isnull(SelectedQty,0)>ToplamIhtiyac*1.1");
            if (drSelectedQty.Length > 0)
                Message += "\nToplam ihtiyacın %10 fazlasından daha fazla metrajda çıktığınız kumaşlar var!\n";

            

            if (XtraMessageBox.Show(Message + "\n\nÇıkış işlemine devam etmek istiyor musunuz ?", "UYARILAR", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No)
                return;

            string xmlArticle = ds.Tables["Table"].Serialize();
            string xmlFoys = ds.Tables["Table1"].Serialize();
            string xmlRolls = ds.Tables["Table2"].Serialize();
            int brandId = ds.Tables["Table3"].Rows[0]["BrandId"].ToInt();
            int sezonId = ds.Tables["Table3"].Rows[0]["SezonId"].ToInt();
            string dosyaNo = ds.Tables["Table3"].Rows[0]["DosyaNo"].ToString();
            int AtelyeId = 0;

            if (ds.Tables["Table4"].Rows.Count == 1)
                AtelyeId = ds.Tables["Table4"].Rows[0]["AtelyeId"].ToInt();

            string OrtakKumasSpName = Sp.Replace("Get", "Create");

            using (CikisEmri ce = new CikisEmri(xmlArticle, xmlFoys, xmlRolls, PlanlamaIds, brandId, sezonId, dosyaNo, CustomerId, false, OrtakKumasSpName, AtelyeId))
                if (ce.ShowDialog() == DialogResult.OK)
                {
                    DataTable dtFoy = ExecuteDataTable("GetSavedOrtakKumasByCikisEmriId", ce.CikisEmriId);
                    byte[] bytes = (byte[])dtFoy.Rows[0]["BLOB"];
                    using (MemoryStream stream1 = new MemoryStream(bytes))
                    using (PrintingSystem ps = new PrintingSystem())
                    using (PrintPreviewFormEx preview = new PrintPreviewFormEx())
                    {
                        ps.LoadDocument(stream1);
                        preview.PrintingSystem = ps;
                        preview.ShowDialog();
                    }

                    bbiOrtakKumas.Enabled = false;

                    CikisEmriId = ce.CikisEmriId;
                    TelaCikisEmriId = ce.TelaCikisEmriId;
                    this.DialogResult = DialogResult.OK;
                }
        }
    }
}
